package com.lagou.edu.factory;

import com.alibaba.druid.util.StringUtils;
import com.lagou.edu.anno.MyAutowried;
import com.lagou.edu.anno.MyService;
import org.reflections.Reflections;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author 应癫
 * <p>
 * 工厂类，生产对象（使用反射技术）
 */
public class BeanFactory {

    /**
     * 任务一：读取解析xml，通过反射技术实例化对象并且存储待用（map集合）
     * 任务二：对外提供获取实例对象的接口（根据id获取）
     */

    private static Map<String, Object> map = new HashMap<>();  // 存储对象


    static {
        Reflections reflections = new Reflections("com.lagou.edu");
        Set<Class<?>> typesAnnotatedWith = reflections.getTypesAnnotatedWith(MyService.class);
        for (Class<?> aClass : typesAnnotatedWith) {
            try {
                Object o = aClass.newInstance();
                MyService annotation = aClass.getAnnotation(MyService.class);
                //注解的别名
                String value = annotation.value();
                if (StringUtils.isEmpty(value)) {
                    Class<?>[] interfaces = aClass.getInterfaces();
                    if (interfaces.length > 0) {
                        String simpleName = interfaces[0].getSimpleName();
                        value = new StringBuilder().append(Character.toLowerCase(simpleName.charAt(0)))
                                .append(simpleName.substring(1)).toString();
                    }
                }
                map.put(value, o);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        if (!map.isEmpty()) {
            map.forEach((k, v) -> {
                //k 就是key，类名首字母小写，v就是实例化的对象
                Class<?> aClass = v.getClass();

                Field[] declaredFields = aClass.getDeclaredFields();
                for (Field declaredField : declaredFields) {
                    if (declaredField.isAnnotationPresent(MyAutowried.class)) {
                        declaredField.setAccessible(true);
                        //TransferServiceImpl.accountDao
                        String name = declaredField.getName();
                        Object o = map.get(name);
                        try {
                            declaredField.set(v, o);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }

    }


    // 任务二：对外提供获取实例对象的接口（根据id获取）
    public static Object getBean(String id) {
        return map.get(id);
    }

}
